﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour {

    //对内部类进行序列化操作，这样它才能被inspactor显示
    [System.Serializable]
    public class Boundary {
        public float xMin, xMax, zMin, zMax;
    }

    //加速参数
    public float speed = 10.0f;
    //边界类实例
    public Boundary boundary;
    //运动时的倾斜度
    public float tilt = 4.0f;

    /*   
     *   Rigidbody组件用于模拟物体的物理状态，比如物体受重力影响，物体被碰撞后的击飞等等。
    注意：关于Rigidbody的调用均应放在FixedUpdate方法中，该方法会在每一次执行物理模拟前被调用。
3.1 Rigidbody.velocity
     设置刚体速度可以让物体运动并且忽略静摩擦力，这会让物体快速从静止状态进入运动状态。
3.2 Rigidbody.AddForce
      给刚体添加一个方向的力，这种方式适合模拟物体在外力的作用下的运动状态。
3.3 Rigidbody.MovePosition
      刚体受到物理约束的情况下，移动到指定点。
4. 通过CharacterController组件移动物体
     CharacterController用于控制第一人称或第三人称角色的运动，使用这种方式可以模拟人的一些行为，比如限制角色爬坡的最大斜度,步伐的高度等。
4.1 CharacterController.SimpleMove
     用于模拟简单运动，并且自动应用重力，返回值表示角色当前是否着地。
4.2 CharacterController.Move
     模拟更复杂的运动,重力需要通过代码实现，返回值表示角色与周围的碰撞信息。*/

    //物理动作前执行,也就是对rigidbody的操作均应放到这里
    private void FixedUpdate()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        //由于游戏本身是2d的，所以不存在纵向移动，y粥位移就是0.0了
        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
        //刚体对象
        Rigidbody rigidbody = GetComponent<Rigidbody>();
        //赋予刚体x和z轴速度
        rigidbody.velocity = movement * speed;

        //这里是通过限制刚体的位置来保证飞船不会飞出屏幕边界
        rigidbody.position = new Vector3(
            //mathF.clamp是限制某个值在最大和最小值之间
            Mathf.Clamp(rigidbody.position.x, boundary.xMin, boundary.xMax),
            0.0f,
            Mathf.Clamp(rigidbody.position.z, boundary.zMin, boundary.zMax)
        );

        //给飞船设定一个倾斜度，使其看起来更有3d感
        rigidbody.rotation = Quaternion.Euler(0.0f, 0.0f, rigidbody.velocity.x * -tilt);
    }
}
